package org.jgs1904.tieba.controller;

import com.google.code.kaptcha.Constants;
import lombok.extern.slf4j.Slf4j;
import org.jgs1904.tieba.entity.User;
import org.jgs1904.tieba.entity.UserMail;
import org.jgs1904.tieba.enums.UserMailStatusEnum;
import org.jgs1904.tieba.service.UserMailService;
import org.jgs1904.tieba.service.UserService;
import org.jgs1904.tieba.utils.UUIDUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;

/**
 * @author junki
 * @date 2020/5/12 14:42
 */
@Controller
@RequestMapping("user")
@SessionAttributes("onlineUser")
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 注入javamail发送bean
     */
    @Autowired
    private JavaMailSender javaMailSender;

    /**
     * 注入thymeleaf的模板引擎
     */
    @Autowired
    private TemplateEngine templateEngine;

    @Autowired
    private UserMailService userMailService;

    @Value("${spring.mail.username}")
    private String mailForm;

    @GetMapping("login")
    public String loginPage() {
        return "user/login";
    }

    @GetMapping("regist")
    public String registPage() {
        return "user/regist";
    }

    @PostMapping("regist")
    public String regist(User user, MultipartFile file) {

        // 判断文件是否为空
        if (file.isEmpty()) {
            return "file is empty";
        }

        // 获取文件保存路径的真实路径
        String realPath = "F:/sbdemoupload/images";

        // 获取原文件名
        String originalFilename = file.getOriginalFilename();

        // 生成随机文件名
        String filename = UUIDUtil.getUUID(8);
        if (originalFilename.contains(".")) {
            filename += originalFilename.substring(originalFilename.lastIndexOf("."));
        }

        // 创建文件对象
        File saveFile = new File(realPath + "/" + filename);

        // 判断路径是否存在
        if (!saveFile.getParentFile().exists()) {
            saveFile.getParentFile().mkdirs();
        }

        // 保存文件
        try {
            file.transferTo(saveFile);
            user.setPhoto(filename);
        } catch (IllegalStateException | IOException e) {
            e.printStackTrace();
        }

        // 密码进行md5加密
        user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));

        // 设置邮箱状态为未激活
        user.setActive((byte) 0);

        User result = userService.save(user);

        return "redirect:/user/login";
    }

    @PostMapping("login")
    public String login(User user, String captcha, @SessionAttribute(Constants.KAPTCHA_SESSION_KEY) String realCaptcha, Model model) {

        // 比较验证码
        if (!realCaptcha.equals(captcha)) {
            model.addAttribute("message", "验证码错误！");
            return "user/login";
        }

        // 密码进行md5加密
        user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));

        User result = userService.getOne(user);

        if (result != null) {
            log.info("登录成功！");
            model.addAttribute("onlineUser", result);
            return "redirect:/post/page";
        } else {
            log.info("登录失败！");
            model.addAttribute("user", user);
            model.addAttribute("message", "用户名密码错误！");
            return "user/login";
        }
    }

    @GetMapping("logout")
    public String logout(HttpServletRequest request, SessionStatus sessionStatus) {

        request.getSession().invalidate(); // httpSession作废

        sessionStatus.setComplete(); // 删除@SessionAttributes中所有属性

        return "redirect:/post/page";
    }

    @GetMapping("forget")
    public String forget() {
        return "user/forget";
    }

    @PostMapping("forget")
    public String forget(String username, String captcha, @SessionAttribute(Constants.KAPTCHA_SESSION_KEY) String realCaptcha, Model model) {

        // 比较验证码
        if (!realCaptcha.equals(captcha)) {
            model.addAttribute("message", "验证码错误！");
            return "user/forget";
        }

        // 查询用户
        User result = userService.getOne(User.builder().username(username).build());
        if (result == null) {
            model.addAttribute("message", "账号不存在！");
            return "user/forget";
        } else {

            try {
                // 发送模板邮件
                MimeMessage message = javaMailSender.createMimeMessage();
                MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
                messageHelper.setFrom(mailForm);
                messageHelper.setTo(result.getEmail());
                messageHelper.setSubject("JGS1904贴吧-激活邮箱");

                // 使用thymeleaf模板
                Context context = new Context();
                // 设置模板数据
                context.setVariable("nickname", result.getNickname());

                // 生成一个token对应用户id
                String token = UUIDUtil.getUUID(132);
                userMailService.save(UserMail.builder().token(token).userId(result.getId()).status(UserMailStatusEnum.UNUSED).build());

                context.setVariable("activeUrl", "http://localhost:8080/user/change/" + token);
                // 将数据绑定到模板
                String emailContent = templateEngine.process("/email/forget", context);
                // 将结果设置到邮件对象
                messageHelper.setText(emailContent, true);

                // 发送邮件
                javaMailSender.send(message);
            } catch (MessagingException e) {
                log.error("激活邮件发送错误==>{}", e.getMessage());
            }

            model.addAttribute("message", "重置密码链接已发送到邮箱！");
            return "user/forget";
        }

    }

    @GetMapping("change/{token}")
    public String change(@PathVariable("token") String token, Model model) {
        model.addAttribute("token", token);
        return "user/change";
    }

    @PostMapping("change")
    public String change(String password, String token, Model model) {
        UserMail userMail = userMailService.changeUserPwdByToken(password, token);
        if (userMail.getStatus().equals(UserMailStatusEnum.USED)) {
            model.addAttribute("message", "密码修改成功！");
        } else {
            model.addAttribute("message", "密码修改失败！");
        }
        return "email/forgetResult";
    }

}
